#include "plugin.h"

#include <maya/MGlobal.h>
#include "main.h"	//For mfnplugin

#include "def.h"
#include "util.h"
#include "sync.h"
#include "gui.h"
#include "net.h"

#pragma message ("remove when VTRY/VCATCH refactored")
#include "..\Global\globaldef.h"

MString VPlugin::g_PluginName = "";
MString VPlugin::g_Title = "ViewerPlugin (Maya)";
MString VPlugin::g_Company = "DacreDenny.com";
MString VPlugin::g_Author = "Dacre Denny";

/**
Returns this plugin as a maya object handle. 

@param pluginObject reference to the pluging handle
@return true if successful, false otherwise
*/
bool VPlugin::GetPlugin(MObject &pluginObject) {

	if(VPlugin::g_PluginName.length() == 0)
		return false;

	MObject plugin = MFnPlugin::findPlugin(VPlugin::g_PluginName);
	if(plugin.hasFn(MFn::kPlugin)) {

		pluginObject = plugin;
		return true;
	}

	return false;
}

/**
Initalizes an instance of this plugin

@param systemObject maya system handle
@return true if successful, false otherwise
*/
bool VPlugin::Initalize(MObject systemObject) {


	try {

		char versionBuffer[512] = {'\0'};
		char apiBuffer[64] = {'\0'};
		/*sprintf_s(versionBuffer,512, "build-maya:\t%s\nbuild-api:\t%i\nbuild-revision:\t%i", MGlobal::mayaVersion().asChar(), MGlobal::apiVersion(), __COUNTER__);
		sprintf_s(apiBuffer,64, "%i", MGlobal::apiVersion());*/
		
		cout << endl;
		cout << "*******************************" << endl;
		cout << VPlugin::g_Title << endl;
		cout << endl;
		cout << VPlugin::g_Author << endl;
		cout << VPlugin::g_Company << endl;
		cout << endl;
		cout << versionBuffer << endl;
		cout << "*******************************" << endl;
		cout << "Starting up.." << endl;

		/**
		Create the plugin instance
		*/
		MStatus status;
		MFnPlugin plugin( systemObject, VPlugin::g_Company.asChar(), versionBuffer, apiBuffer, &status);
		if(MAYA_FAIL(status))
			throw tException("Failed to initalize plugin.");

		if(plugin.name().length() == 0)
			throw tException("Invalid plugin name.");

		VPlugin::g_PluginName = plugin.name();

		cout << "\t- Plugin module initialized" << endl;

		if(!VSyncViewer::InitalizeCallbacks())
			throw tException("Failed to initalize plugin core callbacks");

		cout << "\t- Synchronize module initialized" << endl;

		if(!VGUI::Initialize())
			throw tException("Failed to initalize GUI");

		cout << "\t- GUI module initialized" << endl;

		VNet::HostAddress = "Dacre-PC";

		cout << "\t- Network module initialized" << endl;
		
		/*VSyncViewer::InitPluginSelection();*/
		
		cout << "Success" << endl;
		return true;
	}
	catch(tException exception) {

		VPlugin::HandleException(&exception);
		VGUI::Release();
		VSyncViewer::ReleaseCallbacks();
		VNet::Disconnect();

		return false;
	}
}

void VPlugin::HandleException(tException* pException) {

	if(pException) {
	
		std::string message;
		tException::GetMessage(pException, message);
		cout<<"Exception: "<< message.c_str() <<endl;
	}
	else {

		cout<<"Exception: [error - invalid pointer]"<< endl;
	}
}

bool VPlugin::Release(MObject systemObject) {

	MStatus status;

	cout << endl << "Shutting down " << VPlugin::g_Title << "..." << endl;
	
	/*
	Prevents the selection change from sending anything
	*/
 	const bool disconnected = VNet::Disconnect();

	VSyncViewer::ReleaseRegisteredCallbacks();
	VSyncViewer::ReleaseCallbacks();
	cout << "\t- Synchronize module release: " << (true ? "OK" : "Failed") << endl;
	cout << "\t- GUI module release: " << (VGUI::Release() ? "OK" : "Failed") << endl;
	cout << "\t- Network module release: " << (disconnected ? "OK" : "Failed") << endl;

	cout << "Complete" << endl;
	return true;
}